/*
 * processmgt.h
 *
 *  Created on: 2011-5-25
 *      Author: chenl
 */

#ifndef PROCESSMGT_H_
#define PROCESSMGT_H_

#include "common/common_def.h"
#include "common/common_type.h"
#include "common/common_util.h"
#include "logengine/simplelog.h"
#include "ps_error.h"
#include "taskqueue.h"
#include "tasklist.h"
#include "global.h"

#include <deque>
#include <ext/hash_map>

#include "loki/Singleton.h"

#define for_each_task(MGT, QUEUE, P) \
	for (P = MGT.FirstTaskFrom##QUEUE(); NULL != P; P = MGT.NextTaskFrom##QUEUE(*P))

class CProcessMgt
{
public:
	CProcessMgt();
	virtual ~CProcessMgt();

public:
	int32_t Initialize();
	int32_t Uninitialize();
	int32_t Destroy();

public:
	CTask* CurrentTask()
	{
		return current_;
	}
	CTask* InitTask()
	{
		return init_;
	}
	CTask* GetTaskByPid(pid_t pid)
	{
		return GetTaskFromHashList(pid);
	}

	void SetCurrentTask(CTask& task)
	{
		current_ = &task;
	}

	int32_t NewTask(CTask& oldTask, CTask& newTask);
	int32_t DeleteTask(CTask& task);
	int32_t DeleteTask(pid_t pid);

	int32_t InsertToRunQueue(CTask& task)
	{
		return pRunQueue->InsertTask(task);
	}
	int32_t InsertToWaitQueue(CTask& task)
	{
		return pWaitQueue->InsertTask(task);
	}
	int32_t InsertTaskToHashList(CTask& task)
	{
		return pTaskHashList->InsertTask(task);
	}

	int32_t DelTaskFromRunqueue(CTask& task)
	{
		return pRunQueue->DeleteTask(task);
	}

	int32_t DelTaskFromWaitQueue(CTask& task)
	{
		return pWaitQueue->DeleteTask(task);
	}

	int32_t DelTaskFromHashList(pid_t pid)
	{
		return pTaskHashList->DeleteTask(pid);
	}

	int32_t DelTaskFromProcessTree(CTask& task);

	CTask* GetTaskFromHashList(pid_t pid)
	{
		return pTaskHashList->GetTask(pid);
	}

	CTask* PopFromRunQueue()
	{
		return pRunQueue->Pop();
	}
	CTask* PopFromWaitQueue()
	{
		return pWaitQueue->Pop();
	}

	CTask* FirstTaskFromRunQueue()
	{
		return pRunQueue->FirstTask();
	}
	CTask* NextTaskFromRunQueue(CTask& task)
	{
		return pRunQueue->NextTask(task);
	}

	CTask* FirstTaskFromWaitQueue()
	{
		return pWaitQueue->FirstTask();
	}
	CTask* NextTaskFromWaitQueue(CTask& task)
	{
		return pWaitQueue->NextTask(task);
	}

	int32_t MoveTaskToRunQueueTail(CTask& task)
	{
		return pRunQueue->MoveTaskToTail(task);
	}
	int32_t MoveTaskToWaitQueueTail(CTask& task)
	{
		return pWaitQueue->MoveTaskToTail(task);
	}

	bool IsTaskOnRunQueue(const CTask& task)
	{
		return pRunQueue->IsTaskOnQueue(task);
	}
	bool IsTaskOnWaitQueue(const CTask& task)
	{
		return pWaitQueue->IsTaskOnQueue(task);
	}
	bool IsTaskOnHashList(pid_t pid)
	{
		return pTaskHashList->IsTaskOnList(pid);
	}

	bool IsRunQueueEmpty() const
	{
		return pRunQueue->IsEmtpy();
	}
	bool IsWaitQueueEmpty() const
	{
		return pWaitQueue->IsEmtpy();
	}
	bool IsHashListEmpty() const
	{
		return pTaskHashList->IsEmpty();
	}

public:
	CSimpleLog 			logEngine;
public:
	ITaskQueue* 		pRunQueue;
	ITaskQueue* 		pWaitQueue;
	ITaskList* 			pTaskHashList;
protected:
	CTask* 				init_;
	CTask* 				pRoot_; // process tree
	CTask* 				current_;
};

typedef Loki::SingletonHolder<CProcessMgt> 	ProcessMgt;

#define CREATE_PROCESSMGT_INSTANCE			ProcessMgt::Instance
#define GET_PROCESSMGT_INSTANCE				ProcessMgt::Instance

#endif /* PROCESSMGT_H_ */
